package com.seashell.appstartupjob.job;

import com.seashell.appstartupjob.config.parser.IJobConfigParser;
import com.seashell.appstartupjob.exceptions.JobConfigNotCorrectException;
import com.seashell.appstartupjob.worker.IJobWorker;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.seashell.appstartupjob.config.IJobConfig;

/**
 * com.seashell.appstartupjob.job.AbstractJob
 * 工作抽象类
 *
 * @author Allen
 * @version v1.0
 * @date 2017/7/14
 */
public abstract class AbstractJob implements IJob {

    private static Logger logger = LoggerFactory.getLogger(AbstractJob.class);


    private Class<? extends IJobConfigParser> parserClass;

    private Element configNode;

    private String jobName;

    private IJobConfig jobConfig;

    public AbstractJob(String jobName,Element configNode) {
        this.configNode = configNode;
        this.jobName = jobName;
    }

    public AbstractJob(String jobName,Class<? extends IJobConfigParser> parserClass, Element configNode){
        this(jobName,configNode);
        this.parserClass = parserClass;
    }

    @Override
    public void doJob() {

        /**
         * 解析
         */
        jobConfig = parseConfig();

        /**
         * 获取工人
         */
        IJobWorker worker;
        if(jobConfig.getWorker()==null){
            worker = getDefaultWorker();
        }else{
            try {
                worker = jobConfig.getWorker().newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                logger.error("创建工人:{}出错" , jobConfig.getWorker().getName());
                throw new JobConfigNotCorrectException("创建工人:" + jobConfig.getWorker().getName() + "出错");
            }
        }

        /**
         * 让工人执行任务
         */
        doBeforeWork(jobConfig,worker);
        logger.info("开始执行启动任务:{}",jobName);
        worker.work(this);
        logger.info("启动任务:{} 执行完成!",jobName);

    }

    /**
     * 解析配置文件
     * @return
     */
    private IJobConfig parseConfig(){
        IJobConfigParser parser;
        if(parserClass ==null){
            parser = getDefaultParser();
        }else{
            try {
                parser = parserClass.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                logger.error("Job configuration parser class:{} initial error",parserClass.getName());
                throw new JobConfigNotCorrectException("Job configuration parser class:"
                        + parserClass.getName()
                        + " initial error");
            }
        }
        return parser.parse(configNode);
    }

    @Override
    public String getJobName() {
        if(jobName == null){
            return getDefaultJobName();
        }
        return jobName;
    }

    @Override
    public IJobConfig getJobConfig() {
        return jobConfig;
    }

    /**
     * 获取默认工人
     * @return
     */
    protected abstract IJobWorker getDefaultWorker();

    /**
     * 获取默认解析器
     * @return
     */
    protected abstract IJobConfigParser getDefaultParser();

    /**
     * 获取该类型工作默认名称
     * @return
     */
    protected abstract String getDefaultJobName();

    /**
     * 工作
     * @return
     */
    protected abstract void doBeforeWork(IJobConfig config,IJobWorker worker);

}
